package 每日一题;

/**
 * @description: 小白白刷力扣
 * @author: 小白白
 * @create: 2021-05-13
 **/

public class No1269停在原地的方案数 {

    /**
     * 有一个长度为 arrLen 的数组，开始有一个指针在索引 0 处。
     * 每一步操作中，你可以将指针向左或向右移动 1 步，或者停在原地（指针不能被移动到数组范围外）。
     * 给你两个整数 steps 和 arrLen ，请你计算并返回：在恰好执行 steps 次操作以后，指针仍然指向索引 0 处的方案数。
     * 由于答案可能会很大，请返回方案数 模 10^9 + 7 后的结果。
     *
     * 示例 1：
     * 输入：steps = 3, arrLen = 2
     * 输出：4
     * 解释：3 步后，总共有 4 种不同的方法可以停在索引 0 处。
     * 向右，向左，不动
     * 不动，向右，向左
     * 向右，不动，向左
     * 不动，不动，不动
     * 示例  2：
     * 输入：steps = 2, arrLen = 4
     * 输出：2
     * 解释：2 步后，总共有 2 种不同的方法可以停在索引 0 处。
     * 向右，向左
     * 不动，不动
     * 示例 3：
     * 输入：steps = 4, arrLen = 2
     * 输出：8
     *  
     * 提示：
     * 1 <= steps <= 500
     * 1 <= arrLen <= 10^6
     */

    public int numWays(int steps, int arrLen) {

        /**
         * 遇到这种题,哎~有脑子我不用,我就画x-y二维表格图,直接开始[0,0]找规律,就是玩。
         * x-y想一想对应: 在x步时走到y索引的方法数量
         */
        //步数(包括0步)-下标(取min:如果步长还走不到数组边界)
        int[][] dp=new int[steps+1][Math.min(steps+1,arrLen)];
        int mod= (int) (Math.pow(10,9)+7);

        //0步在0索引处
        dp[0][0]=1;

        for (int i = 1; i <= steps; i++) {
            for (int j = 0; j < dp[0].length; j++) {
                //原地不动
                dp[i][j]+=dp[i-1][j];
                dp[i][j]=Math.floorMod(dp[i][j],mod);
                //左来
                if(j>0){
                    dp[i][j]+=dp[i-1][j-1];
                }
                dp[i][j]=Math.floorMod(dp[i][j],mod);
                //右来
                if(j!=dp[0].length-1){
                    dp[i][j]+=dp[i-1][j+1];
                }
                dp[i][j]=Math.floorMod(dp[i][j],mod);
                if(i==steps){
                    break;
                }
            }
        }

        return dp[steps][0];
    }

    public static void main(String[] args) {
        No1269停在原地的方案数 n=new No1269停在原地的方案数();
        int result = n.numWays(6, 13);
        System.out.println(result);
    }

}
